# coding: utf-8

from celery import shared_task

from lib.live.Im import ImMain
from services.datamodel.share import stats_logger
from django.core.cache import cache
import json
from services.datamodel.live.models import (mm_LiveImUser, mm_Live, mm_LiveImMsg, mm_LiveTally, mm_LiveGroup,
                                            mm_LiveInvitationUser, mm_LivePlayback, mm_LiveData, mm_LiveGoods,
                                            mm_LivePeopleFlow)
import re
from services.datamodel.student.models import mm_Student
import logging
app_logger = logging.getLogger("student")
from lib.live.LiveMain import LiveServers
import time, random
import datetime
import traceback
from django.db.models import F, Sum
from django.db import transaction

# 腾讯直播回调以及Im回调
@shared_task(name="handle_imcallback", ignore_result=True, queue='cpubound')
def handle_imcallback():

    # stats_logger.critical("tencent_imcallback_for_live-------")
    """
    回调参考 https://cloud.tencent.com/document/product/269/1663
    调用对应执行函数
    """
    try:
        cache_group_id = cache.get("live_group_id")
        if cache_group_id:
            group_id = json.loads(cache_group_id)
            for v in set(group_id):
                live = mm_Live.filter(room_id=v).values("id").order_by("-created_at").first()
                g_id = mm_LiveGroup.filter(group_id=str(v)+'_'+str(live['id'])).values('id').first()
                cache_user_id = cache.get('live_user_id_'+str(v))
                if cache_user_id:
                    user_id = json.loads(cache_user_id)
                    for uv in set(user_id):
                        #  获取单个用户点赞数
                        user_like_count = cache.get('user_like_'+str(uv)+'_'+str(v))
                        if not user_like_count:
                            continue
                        # 更新到本组用户点赞
                        group_user = mm_LiveImUser.get_or_default(group_id=g_id['id'], student_id=int(uv))
                        if not group_user:
                            continue
                        group_user.like = F('like')+int(user_like_count)
                        group_user.save()
                        cache.delete('user_like_'+str(uv)+'_'+str(v))
                    cache.delete('live_user_id_'+str(v))
    except:
        err = traceback.format_exc()
        app_logger.error(err)
        return False


# 腾讯直播回调
@shared_task(ignore_result=True, queue='livecallback')
def handle_livecallback(imcallback_data):

    stats_logger.debug("tencent_livecallback_for_live")
    """
    https://cloud.tencent.com/document/product/267/32631
    """
    pass


# 直播购物袋点击率
@shared_task(ignore_result=True)
def handle_shoppingbag_click(live_id, group_id, user_id):

    stats_logger.debug("tencent_shoppingbag_for_live")
    g_id = mm_LiveGroup.filter(group_id=str(group_id)+'_'+str(live_id)).values('id').first()
    mm_LiveTally.create(live_id=live_id, group_id=g_id['id'], student_id=user_id)


@shared_task(ignore_result=True)
def handle_share(live_id, group_id, user_id):
    g_id = mm_LiveGroup.filter(group_id=str(group_id)+'_'+str(live_id)).values('id').first()
    mm_LiveTally.create(live_id=live_id, group_id=g_id['id'], student_id=user_id, types=1)


# trtc开始推送视频回调
@shared_task(ignore_result=True)
def handle_trtc_start_video(status, room_id):
    mm_Live.update_live_status(status=status, room_id=room_id)


@shared_task(ignore_result=True)
def handle_user_join_room(user_id, group_id):
    #  这里的渠道要更改  暂时记录下  后续会更新
    live = mm_Live.filter(room_id=group_id).values("id").order_by("-created_at").first()
    g_id = mm_LiveGroup.filter(group_id=str(group_id)+'_'+str(live['id'])).values('id').first()
    channel = mm_Student.filter(pk=user_id).values('channel').first()
    mm_LiveImUser.update_or_create(student_id=user_id, group_id=g_id['id'], defaults={"channel": channel['channel']})
    # 设置pv
    live_data = mm_LiveData.get_or_default(live_id=live['id'])
    if live_data:
        live_data.pv = F('pv')+1
        if not cache.get('live_uv:'+str(live['id'])+':'+str(user_id)):
            live_data.uv = F('uv')+1
            cache.set('live_uv:'+str(live['id'])+':'+str(user_id), 1, 3600*24)
        live_data.save()
        cache.incr('live_pv_'+str(live['id']), 1)
        return True
    # 这个还要修改
    mm_LiveData.create(
        live_id=live['id'],
        pv=1,
        uv=1
    )
    # 这里记录uv缓存， 一个用户进来只算一次
    cache.set('live_uv:'+str(live['id'])+':'+str(user_id), 1, 3600*24)
    cache.set('live_pv_'+str(live['id']), 1, 3600*24*30)


@shared_task(ignore_result=True)
def handle_user_send_msg(user_id, group_id, msg_time, msg_seq, msg_body):
    app_logger.error(msg_body)
    if msg_body:
        live = mm_Live.filter(room_id=group_id).values("id").order_by("-created_at").first()
        g_id = mm_LiveGroup.filter(group_id=str(group_id)+'_'+str(live['id'])).values('id').first()
        for v in msg_body:
            if str(v['MsgType']) != "TIMCustomElem":
                mm_LiveImMsg.create(
                    from_account_id=int(user_id),
                    group_id=g_id['id'],
                    msg_time=msg_time,
                    msg_seq=msg_seq,
                    msg_body=json.dumps(msg_body)
                )


@shared_task(ignore_result=True)
def handle_exit_room(user_id, group_id, msg_time):
    # live = mm_Live.filter(room_id=group_id).values("id").order_by("-created_at").first()
    # g_id = mm_LiveGroup.filter(group_id=str(group_id)+'_'+str(live['id'])).values('id').first()
    # im_user = mm_LiveImUser.get_or_default(student_id=user_id, group_id=g_id['id'])
    pass


# @shared_task(ignore_result=True)
def handle_strong_regression_room(group_id):
    try:
        from lib.timed_task import scheduler, TimedTaskClass
        if not scheduler.get_job(f"{group_id}_out"):
            with transaction.atomic():
                live = mm_Live.select_for_update().filter(room_id=group_id).first()
                live.status = 4  # status=4表示异常退出
                live.save()
            minutes = 20  # 加入定时任务，时间为minutes分钟后
            scheduler.add_job(TimedTaskClass.end_live, 'date',
                              run_date=datetime.datetime.now()+datetime.timedelta(minutes=minutes), args=[group_id],
                              id=f"{group_id}_out")
            return "定时器添加成功"
        return "定时器添加失败，无需重复添加"
    except:
        err = traceback.format_exc()
        return err

@shared_task(ignore_result=True)
def handle_dismiss_room(group_id, msg_time):
    # 获取本场直播的用户
    try:
        with transaction.atomic():
            live = mm_Live.select_for_update().filter(room_id=group_id).order_by("-created_at").first()
            if live.status != 4:
                live.status = 3
                live.save()
                # 结束直播后，记录直播间剩余观众的退出时间
                exit_time = int(time.time())
                stus = mm_LivePeopleFlow.filter(live=live, status=0)
                for s in stus:
                    mm_LiveImUser.filter(group__live_id=live.id, student_id=s.student_id).update(
                        watch_time=exit_time-s.join_time+F('watch_time'))
                stus.update(status=1, exit_time=exit_time)
                # 发送自定义消息
                if int(live.live_types) == 1:
                    from lib.timed_task import scheduler, TimedTaskClass
                    ImMain().send_group_msg(live.room_id, 12, 3)
                    # 设置定时，推流直播结束10分钟后解散直播群
                    scheduler.add_job(TimedTaskClass.destroy_group, 'date',
                                      run_date=datetime.datetime.now() + datetime.timedelta(minutes=10), args=[group_id],
                                      id=f"{group_id}_out")
                #  更新最高在线
                start_time = live.real_start_time
                end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                res = LiveServers().getStreamPlayInfoList(str(start_time), str(end_time), f"{live.id}_{live.student_id}")
                app_logger.error(f"最高在线人数统计：{res}")
                highest_online = max([i['Online'] for i in res['DataInfoList']]) if res['DataInfoList'] else 0
                mm_LiveData.filter(live_id=live.id).update(highest_online=highest_online)
    except:
        err = traceback.format_exc()
        app_logger.error(err)
        return False


@shared_task(ignore_result=True)
def add_share_user(group_id, share_data):
    try:
        app_logger.error("分享用户添加")
        if 'share_code' in share_data.keys():
            t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
            live = mm_Live.filter(room_id=group_id).values("id").order_by("-created_at").first()
            s_user = mm_Student.filter(share_code=share_data['share_code']).values('id').first()
            mm_LiveInvitationUser.update_or_create(live_id=live['id'], invitation_id=s_user['id'],
                                                   be_invited_id=int(share_data['user_id']), defaults={'updated_at': t})
        return True
    except:
        err = traceback.format_exc()
        app_logger.error(err)
        return False


@shared_task(ignore_result=True)
def get_live_playback(playback_data, room_id):
    try:
        # stream_id = playback_data['stream_id'][0:21]
        # room_id = re.findall(r'groupid=(\d+)', playback_data['stream_param'])[0]
        # room_id = playback_data['stream_id'].split("_")[0]
        live = mm_Live.filter(room_id=room_id).values("id").order_by("-created_at").first()
        if not live:
            return False
        mm_LivePlayback.update_or_create(
            live_id=live['id'], file_id=playback_data['file_id'],
            defaults={"url": playback_data['video_url'], "start_time": playback_data['start_time'],
                      "end_time": playback_data['end_time'], "duration": playback_data['duration'],
                      "file_size": playback_data['file_size'], "playback_pass": random.randrange(1, 99999999, 8)}
        )
        # 记录时间
        duration_sum = mm_LivePlayback.filter(live_id=live['id']).aggregate(total=Sum('duration'))
        mm_LiveData.filter(live_id=live['id']).update(length_of_time=duration_sum['total'],
                                                      playback_of_time=duration_sum['total'])
    except:
        err = traceback.format_exc()
        app_logger.error(err)
        return False


# 直播商品浏览
@shared_task(ignore_result=True)
def handle_goods_browse(live_id, goods_id, user_id):
    goodsObj = mm_LiveGoods.get_or_default(live_id=live_id, goods_id=goods_id)
    if goodsObj:
        goodsObj.pv = F('pv')+1
        if not cache.get('goods_user_id_'+str(live_id)+'_'+str(goods_id)+'_'+str(user_id)):
            goodsObj.uv = F('uv')+1
            cache.set('goods_user_id_'+str(live_id)+'_'+str(goods_id)+'_'+str(user_id), 1, 3600*24)
        goodsObj.save()
        return True
    return True


# 直播商品浏览时间记录
@shared_task(ignore_result=True)
def handle_record_goods_time(live_id, goods_id, times):
    goodsObj = mm_LiveGoods.get_or_default(live_id=live_id, goods_id=goods_id)
    if goodsObj:
        goodsObj.browse_time = F('browse_time')+int(times)
        goodsObj.save()
        return True
    return True

# 用于新用户进入直播间发送推荐商品，发送浏览量
# @shared_task(ignore_result=True)
def send_pv_and_goods(group_id):
    live = mm_Live.filter(room_id=group_id).first()
    goods_id = cache.get(f"{group_id}_push_goods")
    if goods_id:
        ImMain().send_group_msg(group_id, 9, goods_id).json()
    pv = mm_LiveData.get_live_pv(live_id=live.id)
    if pv:
        ImMain().send_group_msg(group_id, 10, pv)